14. Logging
Logging overview
In the code for the
simple_mover
,
arm_mover
, and
look_away
nodes, you may have noticed logging statements such as:
rospy.logwarn('j1 is out of bounds, valid range (%s,%s), clamping to: %s',
min_j1, max_j1, clamped_j1)
and
rospy.loginfo('GoToPositionRequest Received - j1:%s, j2:%s',
req.joint_1, req.joint_2)
Logging statements allow ROS nodes to send messages to a log file or the console. This allows errors and warnings to be surfaced to the user, or log data to be used later for debugging.
By default all logging messages for a node are written to the node's log file which can be found in
~/.ros/log
or
ROS_ROOT/log
. If
roscore
is running, you can use
roscd
to find log file directory by opening a new terminal window and typing:
roscd log
In this directory, you should see directories from runs of your ROS code, along with a
latest
directory with log files from the most recent run.
Below, we'll show some of the options available for logging different types of messages, filtering messages, and changing how messages are surfaced to a user.
Logging levels and outputs
Rospy has several message levels and provides a variety of options for how to display or store these messages:
rospy.logdebug(...)
rospy.loginfo(...)
rospy.logwarn(...)
rospy.logerr(...)
rospy.logfatal(...)
All levels of logging messages are recorded in ROS log files, but some message levels may also be sent to Python
stdout
, Python
stderr
, or the ROS topic
/rosout
.
The
loginfo
messages are written to Python's
stdout
, while
logwarn
,
logerr
, and
logfatal
are written to Python's
stderr
by default. Additionally,
loginfo
,
logwarn
,
logerr
, and
logfatal
are written to
/rosout
.
The following table summarizes the default locations log messages are written to (source here ):
Debug | Info | Warn | Error | Fatal | |
---|---|---|---|---|---|
stdout | X | ||||
stderr | X | X | X | ||
log file | X | X | X | X | X |
/rosout | X | X | X | X |
Filtering and saving log messages from
/rosout
Note that for messages written to
/rosout
, you can see the messages in real time as your program is running by echoing:
rostopic echo /rosout
Although it can be helpful to view messages this way, because of the volume of messages written to that topic, it can sometimes be helpful to filter messages by piping them to grep . These grepped messages can also be saved to a file for debugging:
rostopic echo /rosout | grep insert_search_expression_here
rostopic echo /rosout | grep insert_search_expression_here > path_to_output/output.txt
Modifying message level sent to /rosout
Although
logdebug
messages are not written to
/rosout
by default, it is possible to modify the level of logging messages written to
/rosout
to display them there, or change the level of logging messages written to
/rosout
to be more restrictive. To do this you must set the
log_level
attribute within the
rospy.init_node
code. For example, if you'd like to allow lodebug messages to be written to
/rosout
, that can be done as follows:
rospy.init_node('my_node', log_level=rospy.DEBUG)
Other possible
rospy
options for
log_level
are
INFO
,
WARN
,
ERROR
, and
FATAL
.
Modifying display of messages sent to
stdout
and
stderr
It is also possible to change how messages to
stdout
and
stderr
are displayed or logged. Within a package's
.launch
file, the
output
attribute for a node tag can be set to
"screen"
or
"log"
. The following table summarizes how the different output options change the display of the node's
stdout
and
stderr
messages:
stdout
|
stderr
|
|
---|---|---|
"screen"
|
screen | screen |
"log"
|
log | screen and log |
For example, setting
output="screen"
for the
look_away
node in
robot_spawn.launch
will display both
stdout
and
stderr
messages in the screen:
<!-- The look away node -->
<node name="look_away" type="look_away" pkg="simple_arm" output="screen"/>
If the
output
attribute is left empty, the default is
"log"
.
As you continue on with the project, the ROS systems that you write will become increasingly complex. Being able to use logging effectively may prove extremely useful for debugging!